{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 载入数据\n",
    "data = np.genfromtxt(\"kmeans.txt\", delimiter=\" \")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 计算距离 \n",
    "def euclDistance(vector1, vector2):  \n",
    "    return np.sqrt(sum((vector2 - vector1)**2))\n",
    "  \n",
    "# 初始化质心\n",
    "def initCentroids(data, k):  \n",
    "    numSamples, dim = data.shape\n",
    "    # k个质心，列数跟样本的列数一样\n",
    "    centroids = np.zeros((k, dim))  \n",
    "    # 随机选出k个质心\n",
    "    for i in range(k):  \n",
    "        # 随机选取一个样本的索引\n",
    "        index = int(np.random.uniform(0, numSamples))  \n",
    "        # 作为初始化的质心\n",
    "        centroids[i, :] = data[index, :]  \n",
    "    return centroids  \n",
    "  \n",
    "# 传入数据集和k的值\n",
    "def kmeans(data, k):  \n",
    "    # 计算样本个数\n",
    "    numSamples = data.shape[0]   \n",
    "    # 样本的属性，第一列保存该样本属于哪个簇，第二列保存该样本跟它所属簇的误差\n",
    "    clusterData = np.array(np.zeros((numSamples, 2)))  \n",
    "    # 决定质心是否要改变的变量\n",
    "    clusterChanged = True  \n",
    "  \n",
    "    # 初始化质心  \n",
    "    centroids = initCentroids(data, k)  \n",
    "  \n",
    "    while clusterChanged:  \n",
    "        clusterChanged = False  \n",
    "        # 循环每一个样本 \n",
    "        for i in range(numSamples):  \n",
    "            # 最小距离\n",
    "            minDist  = 100000.0  \n",
    "            # 定义样本所属的簇\n",
    "            minIndex = 0  \n",
    "            # 循环计算每一个质心与该样本的距离\n",
    "            for j in range(k):  \n",
    "                # 循环每一个质心和样本，计算距离\n",
    "                distance = euclDistance(centroids[j, :], data[i, :])  \n",
    "                # 如果计算的距离小于最小距离，则更新最小距离\n",
    "                if distance < minDist:  \n",
    "                    minDist  = distance  \n",
    "                    # 更新样本所属的簇\n",
    "                    minIndex = j  \n",
    "                    # 更新最小距离\n",
    "                    clusterData[i, 1] = distance\n",
    "              \n",
    "            # 如果样本的所属的簇发生了变化\n",
    "            if clusterData[i, 0] != minIndex:  \n",
    "                # 质心要重新计算\n",
    "                clusterChanged = True\n",
    "                # 更新样本的簇\n",
    "                clusterData[i, 0] = minIndex\n",
    "  \n",
    "        # 更新质心\n",
    "        for j in range(k):  \n",
    "            # 获取第j个簇所有的样本所在的索引\n",
    "            cluster_index = np.nonzero(clusterData[:, 0] == j)\n",
    "            # 第j个簇所有的样本点\n",
    "            pointsInCluster = data[cluster_index]  \n",
    "            # 计算质心\n",
    "            centroids[j, :] = np.mean(pointsInCluster, axis = 0) \n",
    "#         showCluster(data, k, centroids, clusterData)\n",
    "  \n",
    "    return centroids, clusterData  \n",
    "  \n",
    "# 显示结果 \n",
    "def showCluster(data, k, centroids, clusterData):  \n",
    "    numSamples, dim = data.shape  \n",
    "    if dim != 2:  \n",
    "        print(\"dimension of your data is not 2!\")  \n",
    "        return 1  \n",
    "  \n",
    "    # 用不同颜色形状来表示各个类别\n",
    "    mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']  \n",
    "    if k > len(mark):  \n",
    "        print(\"Your k is too large!\")  \n",
    "        return 1  \n",
    "  \n",
    "    # 画样本点  \n",
    "    for i in range(numSamples):  \n",
    "        markIndex = int(clusterData[i, 0])  \n",
    "        plt.plot(data[i, 0], data[i, 1], mark[markIndex])  \n",
    "  \n",
    "    # 用不同颜色形状来表示各个类别\n",
    "    mark = ['*r', '*b', '*g', '*k', '^b', '+b', 'sb', 'db', '<b', 'pb']  \n",
    "    # 画质心点 \n",
    "    for i in range(k):  \n",
    "        plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 20)  \n",
    "  \n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "F:\\Anaconda3\\lib\\site-packages\\numpy\\core\\fromnumeric.py:2957: RuntimeWarning: Mean of empty slice.\n",
      "  out=out, **kwargs)\n",
      "F:\\Anaconda3\\lib\\site-packages\\numpy\\core\\_methods.py:73: RuntimeWarning: invalid value encountered in true_divide\n",
      "  ret, rcount, out=ret, casting='unsafe', subok=False)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cluster complete!\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x2876c41b438>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 设置k值\n",
    "k = 4  \n",
    "\n",
    "min_loss = 10000\n",
    "min_loss_centroids = np.array([])\n",
    "min_loss_clusterData = np.array([])\n",
    "\n",
    "for i in range(50):\n",
    "    # centroids 簇的中心点 \n",
    "    # cluster Data样本的属性，第一列保存该样本属于哪个簇，第二列保存该样本跟它所属簇的误差\n",
    "    centroids, clusterData = kmeans(data, k)  \n",
    "    loss = sum(clusterData[:,1])/data.shape[0]\n",
    "    if loss < min_loss:\n",
    "        min_loss = loss\n",
    "        min_loss_centroids = centroids\n",
    "        min_loss_clusterData = clusterData\n",
    "        \n",
    "#     print('loss',min_loss)\n",
    "print('cluster complete!')      \n",
    "centroids = min_loss_centroids\n",
    "clusterData = min_loss_clusterData\n",
    "\n",
    "# 显示结果\n",
    "showCluster(data, k, centroids, clusterData)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 做预测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 1],\n",
       "       [0, 1],\n",
       "       [0, 1],\n",
       "       [0, 1]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 做预测\n",
    "x_test = [0,1]\n",
    "np.tile(x_test,(k,1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 3.53973889,  3.89384326],\n",
       "       [-2.6265299 , -2.10868015],\n",
       "       [ 2.46154315, -1.78737555],\n",
       "       [-2.65077367,  3.79019029]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 误差\n",
    "np.tile(x_test,(k,1))-centroids"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[12.52975144, 15.16201536],\n",
       "       [ 6.89865932,  4.44653198],\n",
       "       [ 6.05919468,  3.19471136],\n",
       "       [ 7.02660103, 14.3655424 ]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 误差平方\n",
    "(np.tile(x_test,(k,1))-centroids)**2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([27.6917668 , 11.34519129,  9.25390604, 21.39214343])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 误差平方和\n",
    "((np.tile(x_test,(k,1))-centroids)**2).sum(axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 最小值所在的索引号\n",
    "np.argmin(((np.tile(x_test,(k,1))-centroids)**2).sum(axis=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def predict(datas):\n",
    "    return np.array([np.argmin(((np.tile(data,(k,1))-centroids)**2).sum(axis=1)) for data in datas])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 画出簇的作用区域"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nhwAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x287691b6b70>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 获取数据值所在的范围\n",
    "x_min, x_max = data[:, 0].min() - 1, data[:, 0].max() + 1\n",
    "y_min, y_max = data[:, 1].min() - 1, data[:, 1].max() + 1\n",
    "\n",
    "# 生成网格矩阵\n",
    "xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),\n",
    "                     np.arange(y_min, y_max, 0.02))\n",
    "\n",
    "z = predict(np.c_[xx.ravel(), yy.ravel()])# ravel与flatten类似，多维数据转一维。flatten不会改变原始数据，ravel会改变原始数据\n",
    "z = z.reshape(xx.shape)\n",
    "# 等高线图\n",
    "cs = plt.contourf(xx, yy, z)\n",
    "# 显示结果\n",
    "showCluster(data, k, centroids, clusterData)  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [default]",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
